package com.quick.develop.flowable.service.definition;

import com.quick.develop.framework.common.page.PageResult;
import com.quick.develop.framework.utils.collection.CollectionUtils;
import com.quick.develop.flowable.domain.definition.BpmProcessDefinitionCreateReqDTO;
import com.quick.develop.flowable.domain.definition.BpmProcessDefinitionPageItemRespVO;
import com.quick.develop.flowable.domain.definition.BpmProcessDefinitionPageReqVO;
import com.quick.develop.flowable.domain.definition.BpmProcessDefinitionRespVO;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;

import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author junyuan.liu
 * @description: 流程定义接口
 * @date 2022/4/21 14:53
 */
public interface IBpmProcessDefinitionService {

    PageResult<BpmProcessDefinitionPageItemRespVO> getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageReqVO);

    /**
     * @param deploymentId 部署编号
     * @return org.flowable.engine.repository.ProcessDefinition
     * @description 获得 deploymentId 对应的 ProcessDefinition
     * @author junyuan.liu
     * @date 2022/4/22 11:07
     */
    ProcessDefinition getProcessDefinitionByDeploymentId(String deploymentId);

    /**
     * 获得 deploymentIds 对应的 ProcessDefinition 数组
     *
     * @param deploymentIds 部署编号的数组
     * @return 流程定义的数组
     */
    List<ProcessDefinition> getProcessDefinitionListByDeploymentIds(Set<String> deploymentIds);

    /***
     * @description 获得 definitionId 对应的 ProcessDefinition
     * @param definitionId 定义ID
     * @return
     * @author junyuan.liu
     * @date 2022/4/25 19:13
     */
    ProcessDefinition getProcessDefinitionListByDefinitionId(String definitionId);

    /**
     * @param definitionIds processDefinitionId
     * @return
     * @description 获得 definitionIds 对应的 ProcessDefinition
     * @author junyuan.liu
     * @date 2022/4/25 19:13
     */
    List<ProcessDefinition> getProcessDefinitionListByDefinitionIds(Set<String> definitionIds);

    /***
     * @description 获得 ids 对应的 ProcessDefinition Map
     * @param ids processDefinitionId
     * @return
     * @author junyuan.liu
     * @date 2022/4/25 19:27
     */
    default Map<String, ProcessDefinition> getProcessDefinitionMap(Set<String> ids) {
        return CollectionUtils.convertMap(
                getProcessDefinitionListByDefinitionIds(ids),
                ProcessDefinition::getId);
    }


    /**
     * @param id
     * @return org.flowable.engine.repository.ProcessDefinition
     * @description 获得编号对应的 ProcessDefinition
     * @author junyuan.liu
     * @date 2022/4/22 10:58
     */
    ProcessDefinition getProcessDefinition(String id);

    /**
     * @param id 部署编号
     * @return org.flowable.engine.repository.Deployment
     * @description 获得 id 对应的 Deployment
     * @author junyuan.liu
     * @date 2022/4/22 11:04
     */
    Deployment getDeployment(String id);

    /**
     * 获得 ids 对应的 Deployment 数组
     *
     * @param ids 部署编号的数组
     * @return 流程部署的数组
     */
    List<Deployment> getDeployments(Set<String> ids);

    /**
     * 获得 ids 对应的 Deployment Map
     *
     * @param ids 部署编号的数组
     * @return 流程部署 Map
     */
    default Map<String, Deployment> getDeploymentMap(Set<String> ids) {
        return CollectionUtils.convertMap(getDeployments(ids), Deployment::getId);
    }


    /**
     * @param processDefinitionId 流程定义的编号
     * @return org.flowable.bpmn.model.BpmnModel
     * @description 获得 Bpmn 模型
     * @author junyuan.liu
     * @date 2022/4/22 16:20
     */
    BpmnModel getBpmnModelByDefinitionId(String processDefinitionId);

    /**
     * @param key 流程定义的标识
     * @return org.flowable.engine.repository.ProcessDefinition
     * @description 获得流程定义标识对应的激活的流程定义
     * @author junyuan.liu
     * @date 2022/4/22 16:45
     */
    ProcessDefinition getActiveProcessDefinitionByKey(String key);

    /**
     * @param key 流程定义的标识
     * @return com.quick.develop.flowable.domain.definition.BpmProcessDefinitionRespVO
     * @description 获得流程定义标识对应的激活的流程定义
     * @author junyuan.liu
     * @date 2022/7/6 15:36
     */
    BpmProcessDefinitionRespVO getActiveProDefByKey(String key);

    /**
     * @param createReqDTO 创建信息
     * @return java.lang.String
     * @description 创建流程定义
     * @author junyuan.liu
     * @date 2022/4/22 16:45
     */
    String createProcessDefinition(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO);

    /**
     * @param deployId 部署ID
     * @param cascade  是否级联删除
     *                 false 删除指定流程部署，如果存在该流程部署的实例job或者历史任务，都会抛出异常
     *                 true 级联删除，删除该流程部署所创建的所有任务信息和历史数据
     * @description 删除流程部署信息
     * @author junyuan.liu
     * @date 2022/5/7 15:36
     */
    void deleteBpmDeployment(String deployId, boolean cascade);

    /**
     * @param createReqDTO 创建信息
     * @return boolean
     * @description 获得需要创建的流程定义，是否和当前激活的流程定义相等
     * @author junyuan.liu
     * @date 2022/4/22 16:30
     */
    boolean isProcessDefinitionEquals(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO);

    /**
     * @param id    流程定义的编号
     * @param state 状态
     * @return
     * @description 更新流程定义状态
     * @author junyuan.liu
     * @date 2022/4/24 9:02
     */
    void updateProcessDefinitionState(String id, Integer state, boolean suspendProcessInstances);


    /**
     * @param listReqVO 列表入参
     * @return
     * @description 获得流程定义列表
     * @author junyuan.liu
     * @date 2022/4/26 11:49
     */
    List<BpmProcessDefinitionRespVO> getProcessDefinitionList(BpmProcessDefinitionPageReqVO listReqVO);

    /***
     * @description 获得流程定义列表 分页 可查询激活或者挂起的 主要用于流程发起
     * @param pageVo
     * @return
     * @author junyuan.liu
     * @date 2022/4/26 11:52
     */
    PageResult<BpmProcessDefinitionRespVO> getProDefPage(BpmProcessDefinitionPageReqVO pageVo);


    /***
     * @description 获得流程定义对应的 BPMN XML
     * @param id 流程部署id
     * @author junyuan.liu
     * @date 2022/4/27 16:06
     */
    String getBpmnXmlByDeploymentId(String id) throws IOException;

    /**
     * @param id 流程定义id
     * @return java.lang.String
     * @description 获得流程定义对应的 BPMN XML
     * @author junyuan.liu
     * @date 2022/6/27 13:15
     */
    String getBpmnXmlByDefinitionId(String id);

    /**
     * @param definitionId definitionId
     * @description
     * @author junyuan.liu
     * @date 2023/3/22 14:37
     */
    void clearDeploymentCache(String definitionId);


}
